package com.mkx.multitier.resource;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 资源使用统计信息类
 */
public class ResourceStatistics {
    // 各类型资源的使用情况
    private final Map<String, ResourceUsage> resourceUsages = new ConcurrentHashMap<>();
    // 总分配次数
    private final AtomicLong totalAllocations = new AtomicLong(0);
    // 总回收次数
    private final AtomicLong totalReleases = new AtomicLong(0);
    // 分配失败次数
    private final AtomicLong allocationFailures = new AtomicLong(0);
    // 当前活动线程数
    private final AtomicLong activeThreads = new AtomicLong(0);
    // 当前资源池中的资源总数
    private final AtomicLong totalResources = new AtomicLong(0);
    
    /**
     * 获取指定类型资源的使用情况
     */
    public ResourceUsage getResourceUsage(String resourceType) {
        return resourceUsages.computeIfAbsent(resourceType, k -> new ResourceUsage());
    }
    
    /**
     * 增加资源分配计数
     */
    public void incrementAllocations(String resourceType) {
        totalAllocations.incrementAndGet();
        getResourceUsage(resourceType).incrementAllocations();
    }
    
    /**
     * 增加资源回收计数
     */
    public void incrementReleases(String resourceType) {
        totalReleases.incrementAndGet();
        getResourceUsage(resourceType).incrementReleases();
    }
    
    /**
     * 增加分配失败计数
     */
    public void incrementAllocationFailures(String resourceType) {
        allocationFailures.incrementAndGet();
        getResourceUsage(resourceType).incrementFailures();
    }
    
    /**
     * 设置当前活动线程数
     */
    public void setActiveThreads(long count) {
        activeThreads.set(count);
    }
    
    /**
     * 获取当前活动线程数
     */
    public long getActiveThreads() {
        return activeThreads.get();
    }
    
    /**
     * 更新资源池大小
     */
    public void updatePoolSize(String resourceType, int maxSize, int availableCount, int allocatedCount) {
        ResourceUsage usage = getResourceUsage(resourceType);
        usage.setMaxSize(maxSize);
        usage.setAvailableCount(availableCount);
        usage.setAllocatedCount(allocatedCount);
    }
    
    /**
     * 获取总分配次数
     */
    public long getTotalAllocations() {
        return totalAllocations.get();
    }
    
    /**
     * 获取总回收次数
     */
    public long getTotalReleases() {
        return totalReleases.get();
    }
    
    /**
     * 获取分配失败次数
     */
    public long getAllocationFailures() {
        return allocationFailures.get();
    }
    
    /**
     * 获取所有资源类型的使用情况
     */
    public Map<String, ResourceUsage> getAllResourceUsages() {
        return new ConcurrentHashMap<>(resourceUsages);
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("ResourceStatistics{\n");
        sb.append("  totalAllocations: " + totalAllocations.get() + ",\n");
        sb.append("  totalReleases: " + totalReleases.get() + ",\n");
        sb.append("  allocationFailures: " + allocationFailures.get() + ",\n");
        sb.append("  activeThreads: " + activeThreads.get() + ",\n");
        sb.append("  resourceDetails: {\n");
        
        for (Map.Entry<String, ResourceUsage> entry : resourceUsages.entrySet()) {
            sb.append("    " + entry.getKey() + ": " + entry.getValue() + ",\n");
        }
        
        sb.append("  }\n");
        sb.append("}");
        return sb.toString();
    }
    
    /**
     * 单个资源类型的使用情况
     */
    public static class ResourceUsage {
        private final AtomicLong allocations = new AtomicLong(0);
        private final AtomicLong releases = new AtomicLong(0);
        private final AtomicLong failures = new AtomicLong(0);
        private int maxSize = 0;
        private int availableCount = 0;
        private int allocatedCount = 0;
        
        public long getAllocations() {
            return allocations.get();
        }
        
        public void incrementAllocations() {
            allocations.incrementAndGet();
        }
        
        public long getReleases() {
            return releases.get();
        }
        
        public void incrementReleases() {
            releases.incrementAndGet();
        }
        
        public long getFailures() {
            return failures.get();
        }
        
        public void incrementFailures() {
            failures.incrementAndGet();
        }
        
        public int getMaxSize() {
            return maxSize;
        }
        
        public void setMaxSize(int maxSize) {
            this.maxSize = maxSize;
        }
        
        public int getAvailableCount() {
            return availableCount;
        }
        
        public void setAvailableCount(int availableCount) {
            this.availableCount = availableCount;
        }
        
        public int getAllocatedCount() {
            return allocatedCount;
        }
        
        public void setAllocatedCount(int allocatedCount) {
            this.allocatedCount = allocatedCount;
        }
        
        public double getUtilizationRate() {
            return maxSize > 0 ? (double) allocatedCount / maxSize * 100 : 0;
        }
        
        @Override
        public String toString() {
            return "{" +
                    "max=" + maxSize + ", " +
                    "available=" + availableCount + ", " +
                    "allocated=" + allocatedCount + ", " +
                    "utilization=" + String.format("%.1f%%", getUtilizationRate()) + ", " +
                    "totalAllocations=" + allocations.get() + ", " +
                    "failures=" + failures.get() +
                    "}";
        }
    }
}
